
#include "SkelMeshNode.h"
#include "Global.h"
#include <d3dx9.h>
#include <d3dx9mesh.h>
#include "IFile.h"
//*************************************************************************************
DWORD FVF[4]=
{
	D3DFVF_XYZB1 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_TEX1,
	D3DFVF_XYZB2 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_TEX1  ,
	D3DFVF_XYZB3 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_TEX1  ,
	D3DFVF_XYZB4 | D3DFVF_LASTBETA_UBYTE4 | D3DFVF_NORMAL | D3DFVF_TEX1  ,
};

void CSkelMeshNode::Term()
{
	if (m_iSerialType == CMeshNodeBase::_SER_D3D)
	{	
		GXRELEASE(m_pD3DMesh);

		if (m_pTexture)
		{
			m_pTexture->Release();
		}
		
		if (m_pD3DBoneCombin)
		{
			LPD3DXBUFFER pBuf = (LPD3DXBUFFER)m_pD3DBoneCombin;
			GXRELEASE(pBuf);
			m_pD3DBoneCombin = NULL;
		}
	}
	else
	{
		if (m_pVertices)
		{
			delete [] m_pVertices;
			m_pVertices = NULL;
		}
		
		if (m_pIdices)
		{
			delete [] m_pIdices;
			m_pIdices = NULL;
		}

	}

	if (m_puD3DBoneCombinCount)
	{
		delete [] m_puD3DBoneCombinCount;
		m_puD3DBoneCombinCount = NULL;
	}
	

}

void CSkelMeshNode::SerialD3D(CIArchive& ar)
{
	if (!ar.IsReading())
	{
		return;
	}

	SerialBase(ar);

	m_iSerialType = _SER_D3D;
	VOID* pVertices;
	VOID* pIdices;
	HRESULT hr;
	hr=D3DXCreateMeshFVF(m_uFaceCount,m_uVertexCount,D3DXMESH_MANAGED,FVF[m_uMaxFaceInfl-1],D3DDEVICE,&m_pD3DMesh);

	if (FAILED(hr))
	{
		return;
	}
	hr=m_pD3DMesh->LockVertexBuffer(0,&pVertices);
	hr=m_pD3DMesh->LockIndexBuffer(0,&pIdices);

	//m_uMeshFVFSize = D3DXGetFVFVertexSize(mesh->GetFVF());
	m_pVertices=(BYTE *)pVertices;
	m_pIdices=(WORD *)pIdices;		

	uint32 uVerSize = m_uMeshFVFSize*m_uVertexCount;
	uint32 uIdSize  = m_uFaceCount*3;

	ar.Serial((char*)m_pVertices,uVerSize);
	ar.Serial((char*)m_pIdices,uIdSize*sizeof(WORD));

	m_pD3DMesh->UnlockVertexBuffer();
	m_pD3DMesh->UnlockIndexBuffer();


	LPD3DXBUFFER pD3dBuf;
	D3DXCreateBuffer(sizeof(D3DXBONECOMBINATION)*m_uPattr,&pD3dBuf);
	m_pD3DBoneCombin = reinterpret_cast<LPD3DXBONECOMBINATION>(pD3dBuf->GetBufferPointer());

	for (int i=0;i<m_uPattr;i++)
	{
		ar.Serial(m_pD3DBoneCombin[i].AttribId);
		ar.Serial(m_pD3DBoneCombin[i].FaceStart);
		ar.Serial(m_pD3DBoneCombin[i].FaceCount);
		ar.Serial(m_pD3DBoneCombin[i].VertexStart);
		ar.Serial(m_pD3DBoneCombin[i].VertexCount);

		m_pD3DBoneCombin[i].BoneId=new DWORD[m_puD3DBoneCombinCount[i]];
		ar.Serial((char*)m_pD3DBoneCombin[i].BoneId,sizeof(DWORD)*m_puD3DBoneCombinCount[i]);
	}

}

void CSkelMeshNode::SerialMem(CIArchive& ar)//to data transform from old
{
	m_iSerialType = _SER_MEM;

	SerialBase(ar);

	uint32 uVerSize = m_uMeshFVFSize*m_uVertexCount;
	uint32 uIdSize  = m_uFaceCount*3;
	if (ar.IsReading())
	{
		m_pVertices = new BYTE[uVerSize];
		m_pIdices   = new WORD[uIdSize];
		m_pD3DBoneCombin = new D3DXBONECOMBINATION[m_uPattr];
	}
	ar.Serial((char*)m_pVertices,uVerSize);
	ar.Serial((char*)m_pIdices,uIdSize*sizeof(WORD));

	for (int i=0;i<m_uPattr;i++)
	{
		ar.Serial(m_pD3DBoneCombin[i].AttribId);
		ar.Serial(m_pD3DBoneCombin[i].FaceStart);
		ar.Serial(m_pD3DBoneCombin[i].FaceCount);
		ar.Serial(m_pD3DBoneCombin[i].VertexStart);
		ar.Serial(m_pD3DBoneCombin[i].VertexCount);
		if (ar.IsReading())
		{
			m_pD3DBoneCombin[i].BoneId=new DWORD[m_puD3DBoneCombinCount[i]];
		}			
		ar.Serial((char*)m_pD3DBoneCombin[i].BoneId,4*m_puD3DBoneCombinCount[i]);
	}
}


void CSkelMeshNode::SerialBase(CIArchive& ar)
{
	CMeshNodeBase::SerialBase(ar);

	SERIALMATR(ar,m_matFCloth);
	SERIALMATR(ar,m_matBCloth);
	ar.Serial(m_uMaxFaceInfl);
	ar.Serial(m_uPattr);
	if (ar.IsReading())
	{
		m_puD3DBoneCombinCount = new uint32[m_uPattr];
	}
	ar.Serial((char*)m_puD3DBoneCombinCount,sizeof(uint32)*m_uPattr);


}
